/**
 * Copyright (c) 2008, Nathan Sweet
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *  3. Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

package com.esotericsoftware.reflectasm.benchmark;

import com.esotericsoftware.reflectasm.ConstructorAccess;

/**
 * Ubuntu20，jdk11, 测试结果reflectasm是10ms左右，jdk是140ms左右。5800H上，3ms对17毫秒
 * ConstructorAccess: 9.453456 ms
 * ConstructorAccess: 9.646027 ms
 * ConstructorAccess: 9.450407 ms
 * ConstructorAccess: 9.666902 ms
 * ConstructorAccess: 9.321129 ms
 * ConstructorAccess: 9.429867 ms
 * ConstructorAccess: 9.2702 ms
 * ConstructorAccess: 9.238599 ms
 * ConstructorAccess: 9.167683 ms
 * ConstructorAccess: 9.215814 ms
 * ConstructorAccess: 9.127077 ms
 * Reflection: 140.6718 ms
 * Reflection: 139.71927 ms
 * Reflection: 139.72531 ms
 * Reflection: 138.44379 ms
 * Reflection: 140.22244 ms
 * Reflection: 138.7786 ms
 * Reflection: 139.51822 ms
 * Reflection: 138.60301 ms
 * Reflection: 140.10649 ms
 * Reflection: 138.2563 ms
 * Reflection: 139.8563 ms
 * Reflection: 138.44879 ms
 * Reflection: 140.01582 ms
 * Reflection: 138.43407 ms
 * Reflection: 140.2099 ms
 * Reflection: 138.70663 ms
 * Reflection: 140.51323 ms
 * Reflection: 141.61888 ms
 * Reflection: 147.49309 ms
 *
 * 改为使用新的api之后，jdk性能有大幅提升，type.newInstance()->type.getDeclaredConstructor().newInstance()。
 * ConstructorAccess: 8.769406 ms
 * ConstructorAccess: 9.392878 ms
 * ConstructorAccess: 8.89644 ms
 * ConstructorAccess: 9.02898 ms
 * ConstructorAccess: 9.189202 ms
 * ConstructorAccess: 9.000367 ms
 * ConstructorAccess: 9.036732 ms
 * ConstructorAccess: 8.845537 ms
 * ConstructorAccess: 9.139193 ms
 * ConstructorAccess: 9.246711 ms
 * ConstructorAccess: 8.779915 ms
 * ConstructorAccess: 8.885731 ms
 * ConstructorAccess: 8.859089 ms
 * Reflection: 35.308372 ms
 * Reflection: 34.916927 ms
 * Reflection: 35.13588 ms
 * Reflection: 49.654617 ms
 * Reflection: 34.69095 ms
 * Reflection: 34.537888 ms
 * Reflection: 35.33469 ms
 * Reflection: 33.015125 ms
 * Reflection: 33.363346 ms
 * Reflection: 33.87715 ms
 * Reflection: 33.229267 ms
 * Reflection: 47.278324 ms
 * Reflection: 33.23549 ms
 * Reflection: 33.08144 ms
 * Reflection: 33.49921 ms
 * Reflection: 33.414604 ms
 * Reflection: 33.41336 ms
 * Reflection: 33.227524 ms
 * Reflection: 33.24076 ms
 * Reflection: 47.258915 ms
 * Reflection: 35.144333 ms
 * Reflection: 33.688084 ms
 * Reflection: 33.77873 ms
 * Reflection: 33.74194 ms
 * Reflection: 33.16084 ms
 */
public class ConstructorAccessBenchmark extends Benchmark {
	public ConstructorAccessBenchmark () throws Exception {
		int count = 1000000;
		Object[] dontCompileMeAway = new Object[count];

		Class<SomeClass> type = SomeClass.class;
		long d = System.currentTimeMillis();
		Object con = type.getDeclaredConstructor(); // 大约1ms
		SomeClass ins = type.getDeclaredConstructor().newInstance(); // 几乎是0
		System.out.println(System.currentTimeMillis() - d);
		d = System.currentTimeMillis();
		ConstructorAccess<SomeClass> access = ConstructorAccess.get(type); // 大约30ms
		System.out.println(System.currentTimeMillis() - d);

		for (int i = 0; i < 100; i++)
			for (int ii = 0; ii < count; ii++)
				dontCompileMeAway[ii] = access.newInstance();
		for (int i = 0; i < 100; i++)
			for (int ii = 0; ii < count; ii++)
				dontCompileMeAway[ii] = type.getDeclaredConstructor().newInstance();
		warmup = false;

		for (int i = 0; i < 100; i++) {
			start();
			for (int ii = 0; ii < count; ii++)
				dontCompileMeAway[ii] = access.newInstance();
			end("ConstructorAccess");
		}
		for (int i = 0; i < 100; i++) {
			start();
			for (int ii = 0; ii < count; ii++)
				dontCompileMeAway[ii] = type.getDeclaredConstructor().newInstance();
			end("Reflection");
		}

		chart("Constructor");
	}

	static public class SomeClass {
		public String name;
	}

	public static void main (String[] args) throws Exception {
		new ConstructorAccessBenchmark();
	}
}
